package com.example.mybaseapp.ui

import android.os.Bundle
import android.text.Layout
import android.util.Log
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.example.mybaseapp.R
import com.example.mybaseapp.widget.ScrollerTextView
import com.therouter.router.Route
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch

//@Route(path="app/FirstActivity")
class FirstActivity : AppCompatActivity() {
    private val data = MutableStateFlow<Int>(0)
    private var totalNum=0
    private lateinit var appCompatTextView:AppCompatTextView
    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)
        appCompatTextView = findViewById(R.id.tx_content)
        initMutableStateFlowView()
        initTextMoreContent()
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }


    }

    private fun initTextMoreContent() {
        val atx = findViewById<ScrollerTextView>(R.id.atx).apply {
            text = getContent()+getContent()
        }
        findViewById<AppCompatButton>(R.id.abtn_select).apply {
            // 获取行高
            val lineHeight: Int = atx.getLineHeight()
// 获取行间距倍数
            val lineSpacingMultiplier: Float = atx.getLineSpacingMultiplier()
// 获取额外的行间距大小
            val lineSpacingExtra: Float = atx.getLineSpacingExtra()
// 通过计算得到实际的行间距（像素）
            var actualLineSpacing = lineHeight * lineSpacingMultiplier + lineSpacingExtra
            actualLineSpacing*=2
            Log.d("Fire", "initTextMoreContent: actualLineSpacing=$actualLineSpacing")

            setOnClickListener {
                    val layout: Layout = atx.layout
                    val scrollY = atx.scrollY
//                    获取当前可见的第一行的开始位置
                    val firstVisibleLineNumber = layout.getLineForVertical(scrollY)
                    val charOffset = layout.getLineStart(firstVisibleLineNumber)

                    val lineEnd = layout.getLineEnd(1)//这个只是获取TextView整体的第二行最后一个字的index

                val lineForVertical =
                    layout.getLineForVertical((scrollY + actualLineSpacing).toInt())
                val lineEnd1 = layout.getLineEnd(lineForVertical)-1


                // 获取当前可见的最后一行的结束位置
                    val lastVisibleLineNumber = layout.getLineForVertical(atx.scrollY + atx.height)
                    val endOffset = layout.getLineEnd(lastVisibleLineNumber)-1//扣掉多出来一个位置，就是最后一行，最后一个文字的位置
                    appCompatTextView.text = "字符偏移量: 起始$charOffset  ${atx.text.toString()[charOffset]}\n" +
                            "结束$lineEnd1 ${atx.text.toString()[lineEnd1]}"
            }
        }
    }

    private fun getContent(): String {
        return "适用于标准应用插件的很多属性也适用于功能模块。下面几部分介绍了应该和不应该包含在功能模块构建配置中的属性。\n" +
                "\n" +
                "不应包含在功能模块 build 配置中的内容\n" +
                "由于每个功能模块都依赖于基本模块，因此它还会继承某些配置。因此，您应该在功能模块的 build.gradle 文件中省略以下内容：\n" +
                "\n" +
                "签名配置：使用您在基本模块中指定的签名配置对 app bundle 进行签名。\n" +
                "minifyEnabled 属性：您只能在基本模块的构建配置中为整个应用项目启用代码缩减。因此，您应该在功能模块中省略此属性。不过，您可以为每个功能模块指定其他 ProGuard 规则。\n" +
                "versionCode 和 versionName：构建 app bundle 时，Gradle 会使用基本模块提供的应用版本信息。您应该在功能模块的 build.gradle 文件中省略这些属性。\n" +
                "与基本模块建立关系\n" +
                "当 Android Studio 创建功能模块时，它会向基本模块的 build.gradle 文件添加 android.dynamicFeatures 属性，以使该功能模块对基本模块可见，如下所示：" +
                "逻辑摄像头和物理摄像头之间的区别\n" +
                "如需了解多摄像头 API，还需要了解逻辑摄像头与物理摄像头之间的区别。作为参考，假设有一台配有三个后置摄像头的设备。在此示例中，三个后置摄像头中的每一个都被视为物理摄像头。\n" +
                "逻辑摄像头是指由两个或更多个物理摄像头组成的分组。\n" +
                "逻辑摄像头的输出可以是来自某个底层物理摄像头的流，也可以是同时来自多个底层物理摄像头的融合流。无论采用哪种方式，数据流都由相机硬件抽象层 (HAL) 进行处理。\n" +
                "\n" +
                "许多手机制造商会开发第一方相机应用，这些应用通常会预安装在其设备上。\n" +
                "为了使用硬件的所有功能，它们可以使用专用 API 或隐藏 API，或者接受其他应用无权访问的驱动程序实现提供的特殊处理。\n" +
                "某些设备通过提供来自不同物理摄像头的融合帧流（但仅向某些特权应用）提供逻辑摄像头的概念。\n" +
                "通常情况下，只有一个物理摄像头向框架公开。下图说明了 Android 9 之前第三方开发者的情况：" +
                "在 MutableSharedFlow 中，通过配置 backpressure，您可以控制数据流的处理速度，从而有效应对快速生产和慢速消费的情况。以下是一些关于 Backpressure 支持的说明：\n" +
                "1. Buffering： 可以设置一个缓冲区大小，以控制上游生产者发送的数据在等待下游消费者处理时能够缓存的数量。如果缓冲区已满，生产者可能会被阻塞或丢弃数据，以确保不会无限制地积累数据。\n" +
                "2. Drop Oldest/Drop Latest： 当缓冲区已满时，可以选择丢弃最旧的数据（Drop Oldest）或者丢弃最新的数据（Drop Latest）。这可以帮助平衡生产者和消费者之间的速度差异。\n" +
                "3. Backpressure Strategy： 可以根据需要选择不同的 Backpressure 策略，\n" +
                "如 BufferOverflow.DROP_OLDEST（缓冲区满时删除最旧项）或 BufferOverflow.DROP_LATEST（缓冲区满时删除最新项）。\n" +
                "通过合理设置 Backpressure 支持，您可以控制数据流的速度，防止数据积累过多，从而更好地处理生产者和消费者之间的速度差异，提高程序的稳定性和性能。\n" +
                "在处理大量数据流的情况下，Backpressure 支持非常重要，可以帮助优化数据处理的效率和资源利用。\n" +
                "同时在线播放多个直播\n" +
                "同时使用多个摄像头视频流介绍了在单个摄像头中同时使用多个视频流的规则。其中一项值得注意的是，同一规则适用于多个摄像头。\n" +
                "CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA 说明了如何将逻辑 YUV_420_888 或原始信息流替换为两个物理信息流。\n" +
                "也就是说，每个 YUV 或 RAW 类型的数据流都可以替换为两个类型和大小相同的数据流。\n" +
                "对于单摄像头设备，您可以先从采用以下保证配置的摄像头数据流开始：\n" +
                "\n" +
                "数据流 1：YUV 类型，逻辑摄像头 (id = 0) 的大小为 MAXIMUM\n" +
                "然后，借助支持多摄像头的设备，您可以创建会话，将该逻辑 YUV 信息流替换为两个物理信息流：\n" +
                "\n" +
                "数据流 1：YUV 类型，MAXIMUM 尺寸（来自实体摄像头）id = 1\n" +
                "数据流 2：YUV 类型，MAXIMUM 尺寸（来自实体摄像头）id = 2\n" +
                "当且仅当两个摄像头属于 CameraCharacteristics.getPhysicalCameraIds() 下的逻辑摄像头分组的一部分时，您才可以将 YUV 或 RAW 流替换为两个等效流。\n" +
                "\n" +
                "该框架提供的保证只是同时从多个物理摄像头获取帧所需的最低要求。大多数设备都支持额外的视频流，有时甚至允许单独打开多个物理摄像头设备。\n" +
                "由于框架并不提供硬性保证，因此要这样做，就需要通过试验和错误测试按设备执行测试和调优。\n" +
                "\n" +
                "创建包含多个物理摄像头的会话\n" +
                "在支持多摄像头的设备上使用物理摄像头时，请打开单个 CameraDevice（逻辑摄像头），并在单个会话中与其互动。\n" +
                "使用 API 级别 28 中的新增 API CameraDevice.createCaptureSession(SessionConfiguration config) 创建单个会话。\n" +
                "会话配置具有多种输出配置，每种输出配置都有一组输出目标，以及（可选）所需的物理摄像头 ID。"
    }

    private  fun initMutableStateFlowView() {

        findViewById<AppCompatButton>(R.id.a_btn_add).apply {
            setOnClickListener{
               data.tryEmit(1)
            }
        }

        lifecycleScope.launch(Main){
            data.collect {value->
                if(value!=0) {
                    totalNum += value
                    appCompatTextView.text = totalNum.toString()
                    data.tryEmit(0)
                }
            }
        }

    }
}